#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
const std::string gpipepath = "./fifo";
const int gdefaultfd = -1;
const int SIZE = 1024;
int read_flags = O_RDONLY;
int write_flags = O_WRONLY | O_APPEND;

int OpenFile(int flags)
{
    int fd = ::open(gpipepath.c_str(), flags);
    if (fd < 0)
    {
        std::cerr << "open error" << std::endl;
        return -1;
    }
    return fd;
}

bool CloseFile(int fd)
{
    if (fd >= 0)
    {
        ::close(fd);
        return true;
    }
    return false;
}

class Init
{
public:
    Init()
    {
        int n = mkfifo(gpipepath.c_str(), 0600);
        if (n < 0)
        {
            std::cerr << "mkfifo error" << std::endl;
            return;
        }
        else
        {
            std::cout << "mkfifo success" << std::endl;
        }
        return;
    }
    ~Init()
    {
        int n = unlink(gpipepath.c_str());
        if (n < 0)
        {
            std::cerr << "unlink error" << std::endl;
        }
        else
        {
            std::cout << "unlink success" << std::endl;
        }
    }
};

Init n;

class Serve
{
public:
    Serve() : _fd(gdefaultfd)
    {
    }

    bool OpenFileForRD()
    {
        // _fd = ::open(gpipepath.c_str(),O_RDONLY);
        // if(_fd<0)
        // {
        //     std::cerr<<"serve open error"<<std::endl;
        //     return false;
        // }
        // return true;
        _fd = OpenFile(read_flags);
        if (_fd < 0)
        {
            return false;
        }
        return true;
    }
    bool CloseFileForRD()
    {
        // if(_fd>=0)
        // {
        //     ::close(_fd);
        //     return true;
        // }
        // return false;
        return CloseFile(_fd);
    }

    int RecPipe()
    {
        int flag;
        int n;
        while (true)
        {
            n = ::read(_fd, &flag, sizeof(flag));
            if (n > 0)
            {
                if (flag == 1)
                {
                    std::cout << "管道接受成功" << std::endl;
                    break;
                }
            }
            else if (n == 0) // 读端关闭
            {
                break;
            }
        }
        return n;
    }
    ~Serve()
    {
    }

private:
    int _fd;
};

class Client
{
public:
    Client() : _fd(gdefaultfd)
    {
    }

    bool OpenFileForWR()
    {
        // _fd = ::open(gpipepath.c_str(),O_WRONLY|O_APPEND);
        // if(_fd<0)
        // {
        //     std::cerr<<"serve open error"<<std::endl;
        //     return false;
        // }
        // return true;
        _fd = OpenFile(write_flags);
        if (_fd < 0)
        {
            return false;
        }
        return true;
    }
    bool CloseFileForWR()
    {
        // if(_fd>=0)
        // {
        //     ::close(_fd);
        //     return true;
        // }
        return CloseFile(_fd);
    }

    void SendPipe()
    {
        // char buff[SIZE] = {0};
        int n = 1;
        ::write(_fd, &n, sizeof(n));
        std::cout << "client pipe send: 1" << std::endl;
    }
    ~Client()
    {
    }

private:
    int _fd;
};
